import { Injectable, UnauthorizedException } from '@nestjs/common';
import { PrismaService } from '../database/prisma.service';
import * as bcrypt from 'bcrypt';

/**
 * 认证服务
 * 零隐患MFIS规范 - 解决隐患：#15 密钥管理
 */
@Injectable()
export class AuthService {
  constructor(private readonly prisma: PrismaService) {}

  async validateUser(username: string, pass: string): Promise<any> {
    try {
      const user = await this.prisma.doctor.findFirst({
        where: {
          username: username,
          is_active: true,
          deleted_at: null,
        },
        select: {
          doctor_id: true,
          username: true,
          password_hash: true,
          email: true,
          role: true,
          is_active: true,
          failed_login_attempts: true,
          locked_until: true,
        },
      });

      if (!user) {
        // 记录失败的登录尝试（如果用户存在但被禁用）
        await this.recordFailedLogin(username);
        return null;
      }

      // 检查账户是否被锁定
      if (user.locked_until && user.locked_until > new Date()) {
        throw new UnauthorizedException('账户已被锁定，请稍后重试');
      }

      // 验证密码
      const isPasswordValid = await bcrypt.compare(pass, user.password_hash);
      if (!isPasswordValid) {
        await this.recordFailedLogin(username, user.doctor_id);
        return null;
      }

      // 重置失败登录计数
      if (user.failed_login_attempts > 0) {
        await this.prisma.doctor.update({
          where: { doctor_id: user.doctor_id },
          data: {
            failed_login_attempts: 0,
            locked_until: null,
            last_login_at: new Date(),
          },
        });
      } else {
        // 更新最后登录时间
        await this.prisma.doctor.update({
          where: { doctor_id: user.doctor_id },
          data: { last_login_at: new Date() },
        });
      }

      // 返回用户信息（不包含密码哈希）
      const { password_hash, ...result } = user;
      return result;

    } catch (error) {
      if (error instanceof UnauthorizedException) {
        throw error;
      }
      return null;
    }
  }

  private async recordFailedLogin(username: string, doctorId?: number): Promise<void> {
    try {
      if (doctorId) {
        const user = await this.prisma.doctor.findUnique({
          where: { doctor_id },
          select: { failed_login_attempts: true },
        });

        if (user) {
          const newAttempts = user.failed_login_attempts + 1;
          const updateData: any = {
            failed_login_attempts: newAttempts,
          };

          // 5次失败后锁定账户30分钟
          if (newAttempts >= 5) {
            updateData.locked_until = new Date(Date.now() + 30 * 60 * 1000);
          }

          await this.prisma.doctor.update({
            where: { doctor_id },
            data: updateData,
          });
        }
      }
    } catch (error) {
      // 忽略记录失败的错误
    }
  }
}